/********************************************************************
# Copyright 2017 Daniel 'grindhold' Brendle
#
# This file is part of parceldude.
#
# parceldude is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either
# version 3 of the License, or (at your option) any later
# version.
#
# parceldude is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with parceldude.
# If not, see http://www.gnu.org/licenses/.
*********************************************************************/

namespace Parceldude {
    [GtkTemplate (ui = "/de/grindhold/parceldude/ui/config.ui")]
    public class ConfigView : Gtk.Paned {
        private List<Installer> installer_paths;
        private ParameterView parameter;
        private MainWindow mw;

        public ConfigView(MainWindow mw) {
            this.mw = mw;
            this.show_all();

            Gtk.TargetEntry[] empty = {};
            this.list.drag_data_received.connect(this.handle_drop);
            this.list.row_selected.connect(this.row_selected);
            Gtk.drag_dest_set(this.list, Gtk.DestDefaults.ALL, empty, Gdk.DragAction.COPY);
            Gtk.drag_dest_add_uri_targets(this.list);

            this.parameter = new ParameterView();
            this.add(this.parameter);
        }

        [GtkChild]
        private Gtk.ListBox list;

        public signal void installers_changed(uint n_installers);

        [GtkCallback]
        public void open_filechooser() {
            Gtk.FileChooserDialog chooser = new Gtk.FileChooserDialog (
				"Select MSI files", this.mw, Gtk.FileChooserAction.OPEN,
				"_Cancel",
				Gtk.ResponseType.CANCEL,
				"_Open",
				Gtk.ResponseType.ACCEPT);

            chooser.select_multiple = true;

            Gtk.FileFilter filter = new Gtk.FileFilter ();
            chooser.set_filter(filter);
            filter.add_mime_type("application/x-msi");
            filter.add_pattern("*.msi");

            if (chooser.run () == Gtk.ResponseType.ACCEPT) {
                var uris = chooser.get_uris ();
                foreach (unowned string path in uris) {
                    this.add_installer(this.uri2path(path));
                }
            }

            chooser.close ();
        }

        private string uri2path(string uri) {
            string path = "";
#if WIN32
            if (uri.has_prefix("file:///") && uri.has_suffix(".msi\0")) {
                path = uri.replace("file:///","");
            }
            else if (uri.has_prefix("file://") && uri.has_suffix(".msi\0")) {
                path = uri.replace("file://","\\\\");
            }
#else
            if (uri.has_prefix("file://") && uri.has_suffix(".msi\0")) {
                path = uri.replace("file://","");
            }
#endif
            return Uri.unescape_string(path);
        }

        private void add_installer(string path) {
            if (!FileUtils.test (path, FileTest.EXISTS)) return;

            // TODO: limit to each packet occuring only once
            var installer = new Installer(path);
            this.list.add(installer);
            installer.destroy.connect(()=>{
                if (!this.has_selected_installer())
                    this.parameter.show_installer(null);
                this.installers_changed(this.get_installers().length());
            });
            this.installers_changed(this.get_installers().length());
        }

        private void handle_drop(Gdk.DragContext ctx, int x, int y, Gtk.SelectionData data, uint info, uint time_) {
            foreach(string text in data.get_uris()) {
                string path = this.uri2path(text);
                this.add_installer(path);
            }
        }

        public unowned List<Installer> get_installers() {
            this.installer_paths = new List<Installer>();
            this.list.@foreach((child)=> {
                var refchild = child as Gtk.ListBoxRow;
                var i = refchild.get_child();
                this.installer_paths.append(i as Installer);
            });
            return this.installer_paths;
        }

        public bool has_selected_installer() {
            bool ret = false;
            this.list.selected_foreach(()=>{
                ret = true;
            });
            return ret;
        }

        public void row_selected(Gtk.ListBoxRow? r) {
            var installer = (Installer)r.get_child();
            if (installer.is_analyzed())
                this.parameter.show_installer(installer);
        }
    }
}
